function Shape(x, y) {			//object constructor
	this.x = x;
	this.y = y;
	this.setAttributes(outlineColor, fillColor, outlineWidth);
};
Shape.prototype.setAttributes = function(outlineColor, fillColor, outlineWidth) {
	this.outlineColor = outlineColor;
	this.fillColor    = fillColor;
	this.outlineWidth = outlineWidth;
	this.alpha = 0.8;
};
Shape.prototype.setDrawAttributes = function(context) {
	context.globalAlpha = this.alpha;
	context.fillStyle   = this.fillColor;
	context.strokeStyle = this.outlineColor;
	context.lineWidth   = this.outlineWidth;
};
//line inherits from shape 
Line.prototype = new Shape();
Line.prototype.constructor = Line;
function Line(x1, y1, x2, y2) {
	Shape.call(this, x1, y1);
	this.dx  = x2 - x1;
	this.dy  = y2 - y1;
	this.len = Math.sqrt(Math.pow(this.dx, 2) + Math.pow(this.dy, 2));
	this.nx  = -this.dy/this.len;
	this.ny  =  this.dx/this.len;
	this.name ="Line";
};
Line.prototype.draw = function(context) {
	this.setDrawAttributes(context);
	context.beginPath();
	context.moveTo(this.x, this.y);
	context.lineTo(this.dx + this.x, this.dy + this.y);
	context.stroke();
};
Line.prototype.contains = function(x, y) {
	return (Math.abs((x - this.x)*(this.nx) + (y - this.y)*(this.ny)) <= this.outlineWidth);
};

Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;
function Rectangle(x1, y1, x2, y2) {
	Shape.call(this, Math.min(x1, x2), Math.min(y1, y2));
	this.w = Math.abs(x1-x2);
	this.h = Math.abs(y1-y2);
	this.name="Rectangle";
}
Rectangle.prototype.draw = function(context) {
	this.setDrawAttributes(context);
	context.beginPath();
	context.rect(this.x, this.y, this.w, this.h);
	context.fill();
	context.stroke();
};
Rectangle.prototype.contains = function(x, y) {
	return (x > this.x && x < this.x+this.w && y > this.y && y < this.y+this.h);
};

Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;
function Circle(x1, y1, x2, y2) {
	Shape.call(this, x1, y1);
	this.r = Math.sqrt(Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));
	this.name="Circle";
};
Circle.prototype.draw = function(context) {
	this.setDrawAttributes(context);
	context.beginPath();
	context.arc(this.x, this.y, this.r, 0, Math.PI*2);
	context.fill();
	context.stroke(); 
};
Circle.prototype.contains = function(x, y) {
	return (Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2)) <= this.r)
};


var canvas;
var context;
var shapes = [];
var selectedShape = null;

function draw() {
	context.clearRect(0, 0, canvas.width, canvas.height);
	for(var i = 0; i < shapes.length; i++)
		shapes[i].draw(context);
};
function clearCanvas() {
	shapes = [];
	draw();
};

var mode         = 0;
var outlineColor = "red";
var fillColor    = "black";
var outlineWidth = 2;

var mouseDown    = false;
var mouseDownX   = 0;
var mouseDownY   = 0;
var mouseUpX     = 0;
var mouseUpY     = 0;

function setMode(newMode) {
	mode = newMode;
};
function setOutlineColor(newOutlineColor) {
	outlineColor = newOutlineColor;
};
function setFillColor(newFillColor) {
	fillColor = newFillColor;
};
function setOutlineWidth(newOutlineWidth) {
	outlineWidth = newOutlineWidth;
};

function mouseDownHandler(e) {
	mouseDown = true;
	mouseDownX = e.pageX - canvas.offsetLeft;
	mouseDownY = e.pageY - canvas.offsetTop;
	switch(mode) {
		case 0:
			if (selectedShape) {
				selectedShape.alpha = 0.8;
				selectedShape = null;
			}
			for(var i = shapes.length-1; i >= 0 && selectedShape == null; i--)
				if (shapes[i].contains(mouseDownX, mouseDownY)) {
					selectedShape = shapes[i];
					selectedShape.alpha = 0.95;
				}
			draw();
			break;
	}
};

function mouseUpHandler(e) {
	mouseUpX = e.pageX - canvas.offsetLeft;
	mouseUpY = e.pageY - canvas.offsetTop;
	if (mouseDown) {
		switch(mode)
		{
			case 0:
				if (selectedShape != null) {
					selectedShape.x = selectedShape.x + (mouseUpX - mouseDownX);
					selectedShape.y = selectedShape.y + (mouseUpY - mouseDownY);
				}
				break;
			case 1:
				shapes.push(new Line(mouseDownX, mouseDownY, mouseUpX, mouseUpY));
				break;
			case 2:
				shapes.push(new Rectangle(mouseDownX, mouseDownY, mouseUpX, mouseUpY));
				break;
			case 3:
				shapes.push(new Circle(mouseDownX, mouseDownY, mouseUpX, mouseUpY));
				break;
		}
		draw();
	}
	mouseDown = false;
};

function mouseMoveHandler(e) {
	xcoord=e.pageX-canvas.offsetLeft;	
	ycoord=e.pageY-canvas.offsetTop;	
	if(mouseDown==true && mode==0 ){
		if(selectedShape.name==="Rectangle"){	
		
			tempW = selectedShape.w;
			tempH = selectedShape.h;
			document.getElementById("test").innerHTML = tempW + "," + tempH + "," + selectedShape.name;
			context.clearRect(0, 0, canvas.width, canvas.height);
			context.beginPath();
			context.rect(xcoord - (tempW / 2), ycoord - (tempH / 2), tempW, tempH);
			context.fill();
			context.stroke(); 

		}
		else if(selectedShape.name==="Line"){
			tempLen=selectedShape.len;
			xcoord=xcoord-(selectedShape.dx/2);
			ycoord=ycoord-(selectedShape.dy/2);
			document.getElementById("test").innerHTML = tempLen+"," + selectedShape.name;
			context.clearRect(0, 0, canvas.width, canvas.height);
			context.beginPath();
			context.moveTo(xcoord,ycoord);
			context.lineTo(selectedShape.dx + xcoord, selectedShape.dy + ycoord);
			context.stroke();
		}
		else if(selectedShape.name==="Circle"){
			radius=selectedShape.r;
			document.getElementById("test").innerHTML = radius+"," + selectedShape.name;
			context.clearRect(0, 0, canvas.width, canvas.height);
			context.beginPath();
			context.arc(xcoord,ycoord,radius,0,Math.PI*2);
			context.fill();
			context.stroke();
			
		}
	}
};

window.onload = function() {
	canvas = document.getElementById("mainCanvas");
	context = canvas.getContext("2d");
		
	canvas.onmousedown = mouseDownHandler;
	canvas.onmouseup   = mouseUpHandler;
	canvas.onmousemove = mouseMoveHandler;	
	
	context.stroke();
};

